package com.jy.project.job;


import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.jy.project.constant.MaterialConstant;
import com.jy.project.domain.*;
import com.jy.project.dto.ApplyDTO;
import com.jy.project.enums.ApplyTypeEnum;
import com.jy.project.enums.ApplyTypeMatericalEnum;
import com.jy.project.enums.DoTaskEnum;
import com.jy.project.enums.QualityStatusEnum;
import com.jy.project.ex.BizException;
import com.jy.project.mapper.*;
import com.jy.project.service.ApplyService;
import com.jy.project.util.CodeUtils;
import com.jy.project.util.CommonStringUtils;
import com.jy.project.util.RedisUtils;
import com.jy.project.vo.MaterialVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@EnableScheduling
@Component
@Slf4j
public class  ApplyCollectJob {

    @Autowired
    private  ApplyMapper applyMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MaterialMapper materialMapper;

    @Autowired
    private ApplyCollectMapper  applyCollectMapper;

    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;


    @Autowired
    TransactionDefinition transactionDefinition;

    @Scheduled(cron = "*/4 * * * * ?")
    public void scanBill(){
      init();

    }

    private synchronized void init(){
        List<Apply> list = listApply();
        for (Apply apply : list) {
            Long useUserId = apply.getUseUserId();
            if (useUserId==null||useUserId==0){
                continue;
            }
            Long applicantUserId = apply.getApplicantUserId();
            ApplyDTO applyDTO=new ApplyDTO();
            applyDTO.setUserId(applicantUserId);
            applyDTO.setUseUserId(useUserId);
            String materialNo = apply.getMaterialNo();
            boolean b = redisUtils.setNX(MaterialConstant.INSERT_STOCK + materialNo,1,24*60*60);
            if (!b){
                continue;
            }
            MaterialVO materialVO = materialMapper.getMaterialVO(materialNo);
            if (materialVO!=null){
                Integer status = materialVO.getUseStatus();
                if (status==1){
                    continue;
                }
            }
            String[] checkMaterialNos={materialNo};
            applyDTO.setCheckMaterialNos(checkMaterialNos);
            this.insertApply(applyDTO,materialVO);

        }
    }

    public List<Apply> listApply(){
        LocalDateTime dateTime = LocalDateTime.now();
        LocalDateTime startTime = LocalDateTime.of(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(), 0, 0,0);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String startFormat = startTime.format(formatter);
        LocalDateTime endTime = LocalDateTime.of(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(), 23, 59,59);
        String endFormat = endTime.format(formatter);
        Example example=new Example(Apply.class);
        example.createCriteria()
                .andGreaterThanOrEqualTo("createAt",startFormat )
                .andLessThanOrEqualTo("createAt",endFormat )
                .andEqualTo("applyType",ApplyTypeEnum.INSERT_MATERIAL.getCode())
                .andEqualTo("status",DoTaskEnum.AGREE.getCode());
        List<Apply> applies = applyMapper.selectByExample(example);
        return  applies;
    }

    public boolean insertApply(ApplyDTO dto, MaterialVO materialVO ) {
        dto.setApplyType(ApplyTypeEnum.COLLECT.getCode());
        Set<Integer> set = new HashSet<>();
        set.add(dto.getApplyType());
        dto.setExt(JSONObject.toJSONString(set));
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            boolean bl = this.insertApplyBusiness(dto,materialVO);
            if (bl == false) {
                throw new BizException("申请领取失败");
            }
        }catch (Exception e){
            dataSourceTransactionManager.rollback(transactionStatus);
            throw  e;
        }
           dataSourceTransactionManager.commit(transactionStatus);
        return true;
    }

    public boolean insertApplyBusiness(ApplyDTO dto, MaterialVO materialVO ) {
        if (dto==null){
            throw new BizException("Apply对象为空");
        }
        Long id = dto.getUserId();
        User user = userMapper.selectByPrimaryKey(id);
        if (user==null){
            throw  new BizException("用户信息可能找不到");
        }
        String[] checkMaterialNos = dto.getCheckMaterialNos();
        if (checkMaterialNos==null){
            throw  new BizException("没有选中信息");
        }
        if (checkMaterialNos.length<0){
            throw  new BizException("没有选中信息");
        }
        //使用人
        User useUser =null;
        if (dto.getUseUserId()!=null&&dto.getUseUserId()!=0){
            useUser= userMapper.selectByPrimaryKey(dto.getUseUserId());
            if (useUser==null){
                throw  new BizException("使用者用户信息找不到");
            }
        }
            Apply ay = this.create();
            ay.setApplyType(dto.getApplyType());
            ay.setName(ApplyTypeEnum.getValue(ay.getApplyType()));
            ay.setApplicantCompanyNo(user.getCompanyNo());
            ay.setApplicantCompanyName(user.getCompanyName());
            ay.setApplicantDeptNo(user.getDeptNo());
            ay.setApplicantDeptName(user.getDeptName());
            ay.setApplicantUserId(user.getId());
            ay.setApplicantUserNickName(user.getNickName());
            if (useUser!=null){
                ay.setUseCompanyNo(useUser.getCompanyNo());
                ay.setUseCompanyName(useUser.getCompanyName());
                ay.setUseDeptNo(useUser.getDeptNo());
                ay.setUseDeptName(useUser.getDeptName());
                ay.setUseUserId(useUser.getId());
                ay.setUseNickName(useUser.getNickName());
            }
            ay.setExt(dto.getExt());
            ay.setRemarks(dto.getRemarks());
            Long managementUserId = materialVO.getManagementUserId();
            ay.setManagementUserId(managementUserId);
            ApplyCollect applyCollect=new ApplyCollect();
            BeanUtils.copyProperties(ay,applyCollect);
            String materialNo = materialVO.getMaterialNo();
            applyCollect.setMaterialNo(materialNo);
            String name = materialVO.getName();
            applyCollect.setMaterialName(name);
            ay.setMaterialNo(materialNo);
            ay.setMaterialName(name);
            applyCollect.setStatus(0);
            applyCollect.setImg(materialVO.getImg());
            applyCollectMapper.insert(applyCollect);
            applyMapper.insertSelective(ay);
            return  true;
    }

    private Apply create() {
        Apply apply = new Apply();
        apply.setApplyNo(CodeUtils.generateApplyNo(ApplyTypeMatericalEnum.SYSTEM_COLLECT.getValue()));
        Date date = new Date();
        apply.setCreateAt(date);
        apply.setUpdateAt(date);
        apply.setUpdateDay(date);
        apply.setIsDelete(0);
        return  apply;

    }
}
